Skip to content

Add Date property type#836

Merged
alistair3149 merged 1 commit into
masterfrom
feature/788-date-property-type
May 22, 2026
Merged

Add Date property type#836
alistair3149 merged 1 commit into
masterfrom
feature/788-date-property-type

Conversation

@malberts

@malberts malberts commented May 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #788

Adds a calendar date property type (a date with no time or timezone component), parallel to the existing dateTime type (#678) and distinct from the planned EDTF type (#679).

Screenshots

Schema editor: type picker. "Date" appears in the type-picker dropdown with its calendar icon, alongside "Date & Time". date-03-type-picker-fixed
Schema editor: Date property attributes. DateAttributesEditor (Range Minimum/Maximum) + DateInput (Initial value), all native <input type="date">. date-04-property-editor-filled
Subject edit: DateInput value editor. Native date input on the subject form, pre-populated 06/15/2026, with min/max pulled from the schema bounds. date-05-subject-edit
Subject display: DateDisplay. EventDate rendered as Jun 15, 2026: a <time datetime="2026-06-15"> with locale-formatted text, no time/tz component. date-06-subject-display

Behavior

Values are ISO 8601 calendar dates (YYYY-MM-DD), with optional inclusive minimum/maximum bounds of the same shape.

Design note: why mirror DateTime rather than extract shared abstractions

Date is a deliberate near-clone of DateTime (#678): same class shape, same wire format, same registration pattern, narrower input. We considered extracting a shared base class / validation helper and chose not to, for these reasons:

  • The similarity is largely superficial. Date and DateTime line up almost diff-for-diff, but the differences (value space, timezone semantics, display format) are semantic, not cosmetic. An abstraction extracted from two examples typically either erases those differences (wrong) or surfaces them as a tangle of configuration options (worse than the duplication). Two examples isn't enough to tell which similarities are essential.
  • Adjacent work will reshape what the abstraction would look like. Add type-aware persistence for statement values in Neo4j #831 (type-aware Neo4j persistence) is going to change the value-builder contract in ways that affect both types together; extracting now and re-shaping then is more churn than letting the pattern emerge.
  • Mechanical parity made the review audit cheap. Each layer of Date lines up with its DateTime counterpart 1:1, so "is anything from the DateTime follow-ups missing?" reduces to a readable diff. We confirmed all the substantive fixes from Add DateTime min/max cross-validation and generalize minExceedsMax #733, DateTime: stricter ISO 8601 value validation #734, DateTime: user-local display/input with UTC storage and semantic <time> #753, and DateTimeInput: format min/max error bounds as host-local wall-clock #770 are present.
  • The promising extraction targets are cross-type, not Date↔DateTime-specific. The TS validate() body shape (required → parse → invalid-X → min → max) is structurally identical in Date, DateTime, and (with adaptation) Number; the PHP ensureValidBoundOrNull pattern is the same wherever there's a bounded scalar property. These are worth lifting once there are 3+ consumers: best done as a separate follow-up, not bundled with adding the second consumer.

The Vue input/display/attributes-editor trio is explicitly not a good extraction target: the duplication is shallow per file (~100 lines), the differences are the seam (input-type, icon, conversion module, class prefix), and a generic wrapper would just move the duplication into a configuration object.

Verification

  • PHP suite passes; phpcs clean; phpstan level 9 reports no errors.
  • JS: full suite (incl. new specs) passes; eslint clean; vue-tsc typecheck clean.
  • review-tests mutation testing on all new test files: all realistic mutations caught (two provably-equivalent survivors, documented).
  • Browser verification in a dedicated isolated stack confirmed end to end: the four screenshots above show the type picker, schema property attributes, subject edit form, and subject display all behaving as specified.

🤖 Generated with Claude Code

@malberts malberts force-pushed the feature/788-date-property-type branch 3 times, most recently from cf0ff43 to 03b9d1a Compare May 22, 2026 13:31
@malberts malberts marked this pull request as ready for review May 22, 2026 14:05
@malberts malberts force-pushed the feature/788-date-property-type branch 2 times, most recently from 992f4a7 to 1087d9a Compare May 22, 2026 15:02
@alistair3149 alistair3149 self-requested a review May 22, 2026 17:59
Adds a calendar `date` property type — a date with no time or timezone
component — parallel to the existing `dateTime` type and distinct from
the planned EDTF type.

Values are strict ISO 8601 calendar dates in `YYYY-MM-DD` form. Values
carrying a time/timezone component, partial values (year-only,
year-month), and calendar overflows (e.g. `2025-02-30`, Feb 29 in a
non-leap year) are rejected. Optional inclusive `minimum`/`maximum`
bounds follow the same shape rules.

Backend:
- `DateType` property type and `DateProperty` schema definition,
  mirroring the DateTime equivalents with a date-only regex plus a
  `checkdate` calendar-overflow guard.
- Registered in `PropertyTypeRegistry::withCoreTypes()` and as a Neo4j
  scalar builder in `Neo4jValueBuilderRegistry::withCoreBuilders()`.

Frontend:
- `Date.ts` (validation, strict parsing, locale display formatting),
  `dateConversion.ts` (parse-guarded `<input type="date">` wire
  conversion), and `DateInput` / `DateDisplay` / `DateAttributesEditor`
  Vue components.
- Registered in `Neo.ts`, `NeoWikiExtension.ts`, and exported from
  `public-api.ts`.

i18n: `neowiki-property-type-date` label and `neowiki-field-invalid-date`
validation message, with qqq documentation and extension.json message
registration.

Tests: PHP `DateTypeTest`, `DatePropertyTest`, an extended Neo4j
value-builder assertion, and a CodexModule icon registration guard.
TS specs for the domain type, conversion helpers, and all three Vue
components.

Identified with Claude Code

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@alistair3149 alistair3149 force-pushed the feature/788-date-property-type branch from 1087d9a to a4da3c6 Compare May 22, 2026 18:21
@alistair3149 alistair3149 merged commit 674bf78 into master May 22, 2026
12 checks passed
@alistair3149 alistair3149 deleted the feature/788-date-property-type branch May 22, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add date property type

2 participants